﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Net;
using System.Collections;
using System.Threading;
using System.Diagnostics;
using System.Configuration;

namespace AddToCart
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly string caProducttionID = "MD234C";
        private readonly string hkProducttionID = "MD235ZP";
        private readonly string caCountry = "ca";
        private readonly string hkCountry = "hk-zh";

        private readonly string urlTemp = @"http://store.apple.com/{0}/configure/{1}/A?option.iphone_applecare=none&option.iphone_bumpers=none&option.digital_av_adapter=none&option.iphone_4_dock=none&option.additional_apple_usb_power_adaptor=none&option.additional_apple_dock_connector_to_usb_cable=none&add-to-cart=add-to-cart&cppart=UNLOCKED%2FWW";
        private readonly string refererTemp = @"http://store.apple.com/{0}/configure/{1}/A?select=select&product={1}%2FA&cppart=UNLOCKED%2FWW";
        private readonly string cartTemp = @"http://store.apple.com/{0}/cart";

        public MainWindow()
        {
            InitializeComponent();
        }

        private string currentCountry;
        private string currentProducttionID;

        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            startButton.IsEnabled = false;
            currentCountry = hkRadioButton.IsChecked == true ? hkCountry : caCountry;
            currentProducttionID = hkRadioButton.IsChecked == true ? hkProducttionID : caProducttionID;

            Process rundll = Process.Start("rundll32.exe", "InetCpl.cpl,ClearMyTracksByProcess 2");
            rundll.WaitForExit();
            webBrowser.Navigate(string.Format(cartTemp, currentCountry));
        }

        private int count = 0;

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            lock (syncObjectForStart)
            { 
            }
            
            BackgroundWorker worker = sender as BackgroundWorker;
            int sleep = int.Parse(ConfigurationManager.AppSettings.Get("Sleep"));
            bool needSleep = sleep == 0 ? false : true;

            string cookie = Application.GetCookie(new Uri("http://store.apple.com"));

            HttpWebRequest request;
            HttpWebResponse response;

            while(true)
            {
                Interlocked.Increment(ref count);
                worker.ReportProgress(count);
                if (needSleep == true)
                {
                    Thread.Sleep(sleep);
                }

                request = WebRequest.Create(string.Format(urlTemp, currentCountry, currentProducttionID)) as HttpWebRequest;
                request.AllowAutoRedirect = false;
                request.Method = "GET";
                request.Headers.Add("Cookie", cookie);
                request.Headers.Add("Cache-Control", "no-cache");
                request.Referer = string.Format(refererTemp, currentCountry, currentProducttionID);
                request.Host = "store.apple.com";

                response = request.GetResponse() as HttpWebResponse;

                if (response.StatusCode == HttpStatusCode.SeeOther)
                {
                    string location = response.Headers["Location"];
                    bool bingo = false;
                    if (location.Contains("cart") == true)
                    {
                        bingo = true;
                    }
                    if (location.Contains("not_available") == true)
                    {
                        bingo = false;
                    }
                    if (bingo == true)
                    {
                        break;
                    }
                }
            }
        }

        private void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            countLabel.Content = e.ProgressPercentage;
        }

        private object syncObjectForStart = new object();

        private object syncObjectForComplete = new object();

        private bool gotIt = false;

        private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lock (syncObjectForComplete)
            {
                if (gotIt == false)
                {
                    gotIt = true;
                    webBrowser.Navigate(string.Format(cartTemp, currentCountry));
                    foreach (var item in workers)
                    {
                        if (sender != item)
                        {
                            item.CancelAsync();
                        }
                    }
                }
            }
        }

        private List<BackgroundWorker> workers = new List<BackgroundWorker>();

        private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            webBrowser.LoadCompleted -= webBrowser_LoadCompleted;
            
            int concurrent = int.Parse(ConfigurationManager.AppSettings.Get("Concurrent"));
            lock (syncObjectForStart)
            {
                for (int i = 0; i < concurrent; i++)
                {
                    BackgroundWorker worker = new BackgroundWorker();
                    worker.WorkerSupportsCancellation = true;
                    worker.WorkerReportsProgress = true;
                    worker.DoWork += this.DoWork;
                    worker.ProgressChanged += this.ProgressChanged;
                    worker.RunWorkerCompleted += this.RunWorkerCompleted;
                    worker.RunWorkerAsync();
                    workers.Add(worker);
                }
            }
        }
    }
}
